﻿using Accord.Imaging;
using Accord.Video;
using Accord.Video.DirectShow;
using Accord.Vision.Tracking;
using MDK.Device;
using Newtonsoft.Json;
using System;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows.Forms;

namespace MDK.Winform.UserControl.Config
{
    public partial class Camera : BaseForm
    {
        private IVideoSource videoSource = null;
        private string MonikerString;
        private string DeviceName;
        Camshift tracker = null;

        private IdentificationCamera Identification;
        public Camera()
        {
            InitializeComponent();
            GetIdentificationCamera();
        }

        public void GetIdentificationCamera()
        {
            string fp = Application.StartupPath + "\\IdentificationCamera.json";
            if (File.Exists(fp))
            {
                Identification = JsonConvert.DeserializeObject<IdentificationCamera>(File.ReadAllText(fp));  // 尖括号<>中填入对象的类名 
                txtX.Value = Identification.Pallet.X;
                txtY.Value = Identification.Pallet.Y;
                txtWidth.Value = Identification.Pallet.Width;
                txtHeight.Value = Identification.Pallet.Height;

                txtCenterX.Value = Identification.Center.X;
                txtCenterY.Value = Identification.Center.Y;
                txtCenterWidth.Value = Identification.Center.Width;
                txtCenterHeight.Value = Identification.Center.Height;

                txtCenterBrin.Value = Identification.CenterFilter;
                txtNullBrin.Value = Identification.NullFilter;
                HMin2.Value = Identification.TubeType2.HueMin;
                HMax2.Value = Identification.TubeType2.HueMax;
                SMin2.Value = (int)Identification.TubeType2.SaturationMin;
                SMax2.Value = (int)Identification.TubeType2.SaturationMax;
                LMin2.Value = (int)Identification.TubeType2.LightnessMin;
                LMax2.Value = (int)Identification.TubeType2.LightnessMax;
                TubeMIN2.Value = Identification.TubeType2.TubeMin;
                TubeMax2.Value = Identification.TubeType2.TubeMax;
            }   HMin1.Value = Identification.TubeType1.HueMin;
                HMax1.Value = Identification.TubeType1.HueMax;
                SMin1.Value = (int)Identification.TubeType1.SaturationMin;
                SMax1.Value = (int)Identification.TubeType1.SaturationMax;
                LMin1.Value = (int)Identification.TubeType1.LightnessMin;
                LMax1.Value = (int)Identification.TubeType1.LightnessMax;
                TubeMIN1.Value = Identification.TubeType1.TubeMin;
                TubeMax1.Value = Identification.TubeType1.TubeMax;
           
        }

        private void SetIdentificationCamera()
        {
            var Identification = new IdentificationCamera();
            Identification.Pallet.X = txtX.Value;
            Identification.Pallet.Y = txtY.Value;
            Identification.Pallet.Width = txtWidth.Value;
            Identification.Pallet.Height = txtHeight.Value;
            Identification.Center.X = txtCenterX.Value;
            Identification.Center.Y = txtCenterY.Value;
            Identification.Center.Width = txtCenterWidth.Value;
            Identification.Center.Height = txtCenterHeight.Value;

            Identification.CenterFilter = txtCenterBrin.Value;
            Identification.NullFilter = txtNullBrin.Value;

            Identification.TubeType1.Id = 1;
            Identification.TubeType1.Name = "酶免";
            Identification.TubeType1.HueMin = (int)HMin1.Value;
            Identification.TubeType1.HueMax = (int)HMax1.Value;
            Identification.TubeType1.SaturationMin = (float)SMin1.Value;
            Identification.TubeType1.SaturationMax = (float)SMax1.Value;
            Identification.TubeType1.LightnessMin = (float)LMin1.Value;
            Identification.TubeType1.LightnessMax = (float)LMax1.Value;
            Identification.TubeType1.TubeMin = (int)TubeMIN1.Value;
            Identification.TubeType1.TubeMax = (int)TubeMax1.Value;
            Identification.TubeType2.Id = 2;
            Identification.TubeType2.Name = "核酸";
            Identification.TubeType2.HueMin = (int)HMin2.Value;
            Identification.TubeType2.HueMax = (int)HMax2.Value;
            Identification.TubeType2.SaturationMin = (float)SMin2.Value;
            Identification.TubeType2.SaturationMax = (float)SMax2.Value;
            Identification.TubeType2.LightnessMin = (float)LMin2.Value;
            Identification.TubeType2.LightnessMax = (float)LMax2.Value;
            Identification.TubeType2.TubeMin = (int)TubeMIN2.Value;
            Identification.TubeType2.TubeMax = (int)TubeMax2.Value;

            string fp = Application.StartupPath + "\\IdentificationCamera.json";
            if (!File.Exists(fp))  // 判断是否已有相同文件 
            {
                FileStream fs1 = new FileStream(fp, FileMode.Create, FileAccess.ReadWrite);
                fs1.Close();
            }
            File.WriteAllText(fp, JsonConvert.SerializeObject(Identification));

        }

        private void CloseVideoSource()
        {
            this.Cursor = Cursors.WaitCursor;
            videoSourcePlayer.SignalToStop();
            for (int i = 0; (i < 50) && (videoSourcePlayer.IsRunning); i++)
            {
                Thread.Sleep(100);
            }
            if (videoSourcePlayer.IsRunning)
                videoSourcePlayer.Stop();

            videoSourcePlayer.BorderColor = Color.Black;
            this.Cursor = Cursors.Default;
        }

        private void OpenVideoSource(IVideoSource source)
        {
            this.Cursor = Cursors.WaitCursor;
            CloseVideoSource();
            videoSourcePlayer.VideoSource = source;
            videoSourcePlayer.Start();
            videoSource = source;
            
            this.Cursor = Cursors.Default;
        }

        private static VideoCapabilities selectResolution(VideoCaptureDevice device)
        {
            foreach (var cap in device.VideoCapabilities)
            {
                int value = 0;
                CameraControlFlags valueEnum;
                device.GetCameraProperty(CameraControlProperty.Exposure, out value, out valueEnum);
            }
            return device.VideoCapabilities.First();
        }

        private void Camera_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (videoSourcePlayer.IsRunning)
            {   // 停止视频
                videoSourcePlayer.SignalToStop();
                videoSourcePlayer.WaitForStop();
                videoSourcePlayer.Stop();
            }
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            //Bitmap bitmap = videoSourcePlayer.GetCurrentVideoFrame();
            //bitmap.Save(@"D:/1.png");
            //这里停止摄像头继续工作 当然videoSourcePlayer里也定义了 Stop();用哪个都行
            //videoSourcePlayer.Stop();
            SetIdentificationCamera();
        }

        private void videoSourcePlayer_NewFrame(object sender, ref Bitmap image)
        {
            Rectangle rect = new Rectangle((int)Identification.Pallet.X, (int)Identification.Pallet.Y, (int)Identification.Pallet.Width, (int)Identification.Pallet.Height);
            Rectangle rect1 = new Rectangle((int)Identification.Center.X, (int)Identification.Center.Y, (int)Identification.Center.Width, (int)Identification.Center.Height);
            PalletBitmapHelper.Init(rect, rect1, (int)Identification.CenterFilter, (int)Identification.NullFilter, new TubeTypeIdentifyFilter[] { Identification.TubeType1 ,Identification.TubeType2});
            Bitmap outmap;
            PalletBitmapHelper.IdentifyTubeTypes(image, out outmap);
            image = outmap;
        }

        private void btnOpenCamera_Click(object sender, EventArgs e)
        {
            CameraDevice form = new CameraDevice();
            if (form.ShowDialog(this) == DialogResult.OK)
            {
                MonikerString = form.VideoDevice;
                DeviceName = form.VideoDeviceName;
                VideoCaptureDevice videoSource = new VideoCaptureDevice(MonikerString);
                videoSource.VideoResolution = selectResolution(videoSource);
                OpenVideoSource(videoSource);
            }
        }

        private void btnParameterset_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(MonikerString)) return;
            CameraSet set = new Config.CameraSet(MonikerString, DeviceName);
            set.ShowDialog();
        }
    }
}
